package Control;

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Image;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

import Entity.Shop_Customization;
import Entity.Shop_Product;
import Entity.Workshop_ReportEntity;
import Entity.Workshop_WorkshopCategory;
import Entity.Workshop_WorkshopEntity;
import Form.Workshop_Report_Form;

public class Workshop_Report_Controller {
	//Object Attributes
	private Workshop_Report_Form parser;
	private Workshop_ReportEntity report;
	private Workshop_WorkshopCategory selectedCategory = new Workshop_WorkshopCategory();
	private ArrayList<Workshop_WorkshopCategory> categoryList = new ArrayList<Workshop_WorkshopCategory>();
	private ArrayList<Workshop_WorkshopEntity> workshopList = new ArrayList<Workshop_WorkshopEntity>();

	public Workshop_Report_Form getParser() {
		return parser;
	}

	public void setParser(Workshop_Report_Form parser) {
		this.parser = parser;
	}

	public Workshop_ReportEntity getReport() {
		return report;
	}

	public void setReport(Workshop_ReportEntity report) {
		this.report = report;
	}

	public Workshop_WorkshopCategory getSelectedCategory() {
		return selectedCategory;
	}

	public void setSelectedCategory(Workshop_WorkshopCategory selectedCategory) {
		this.selectedCategory = selectedCategory;
	}

	public Workshop_Report_Controller(final Workshop_Report_Form parser){
		this.setParser(parser);
		this.setReport(new Workshop_ReportEntity());
		
		Calendar calendarDate = Calendar.getInstance();
		getParser().getMonthCombo().setSelectedIndex(calendarDate.get(Calendar.MONTH));
		
		SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>()
		{
			@Override
			protected Void doInBackground() throws Exception {
				categoryList = Workshop_WorkshopCategory.retrieveAllCategory();
				return null;
			}
			
			protected void done(){	
				getParser().getCategoryPanel().setPreferredSize(new Dimension(170, categoryList.size() * 50));
				for(int i = 0; i < categoryList.size(); i++){
					final int tempIndex = i;
					
					final JPanel category = new JPanel();
					final JLabel categoryName = new JLabel(categoryList.get(i).getDescription());
					
					category.setPreferredSize(new Dimension(170, 40));
					category.setOpaque(false);
					
					category.addMouseListener(new MouseListener(){

						@Override
						public void mouseClicked(MouseEvent arg0) {
							setSelectedCategory(categoryList.get(tempIndex));
							
							CardLayout cl = (CardLayout)(getParser().getCardPanel().getLayout());
						    cl.show(getParser().getCardPanel(), "items");
				    		getParser().getTabbedPane().setEnabledAt(1, true);
				    		getParser().getTabbedPane().setSelectedIndex(1);
				    		getParser().getTabbedPane().setEnabledAt(2, true);
				    		
						    SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>()
						    {
								@Override
								protected Void doInBackground() throws Exception {
								    report.retrieveProdsUnderCat(categoryList.get(tempIndex).getCategoryCode(), getParser().getMonthCombo().getSelectedIndex());
								    workshopList = Workshop_WorkshopEntity.retrieveOBSWorkshopUnderCat(categoryList.get(tempIndex), getParser().getMonthCombo().getSelectedIndex());
									return null;
								}
						    	
						    	protected void done(){
						    		generateItems();
						    		generateWorkshopReport();
						    		generatePastWorkshops();
									parser.getParser().closeProgressBar();
						    	}
						    };
							parser.getParser().getProgressBar();						    
						    worker.execute();
						}

						@Override
						public void mouseEntered(MouseEvent arg0) {
							category.setOpaque(true);
							category.setBackground(SystemColor.desktop);
							categoryName.setForeground(Color.WHITE);
						}

						@Override
						public void mouseExited(MouseEvent arg0) {
							category.setOpaque(false);
							category.setBackground(null);
							categoryName.setForeground(null);
						}

						@Override
						public void mousePressed(MouseEvent arg0) {							
						}
						@Override
						public void mouseReleased(MouseEvent arg0) {
						}
						
					});
					
					categoryName.setPreferredSize(new Dimension(170, 30));
					categoryName.setFont(new Font("Tahoma", Font.PLAIN, 15));
					categoryName.setHorizontalAlignment(SwingConstants.CENTER);
					category.add(categoryName);
					
					getParser().getCategoryPanel().add(category);
				}
				getParser().getCategoryPanel().repaint();
				getParser().getCategoryPanel().revalidate();
				parser.getParser().closeProgressBar();
			}
		};
		parser.getParser().getProgressBar();
		worker.execute();
	}
	
	public void generateSalesReport(){
		report.getDate().set(Calendar.MONTH, getParser().getMonthCombo().getSelectedIndex());
		report.getReportDetails();
		getParser().refreshProductStatistics();
	}
	
	public void generateItems(){
		getParser().getItemPanel().removeAll();
		getParser().getItemPanel().repaint();
		getParser().getItemPanel().revalidate();
		
		//getCatProds - products
		//getProdCustomizations - customization
		report.retrieveProdsUnderCat(getSelectedCategory().getCategoryCode(), getParser().getMonthCombo().getSelectedIndex());
		
		//Remove product with no customization
		ArrayList<Shop_Product> prodToRemove = new ArrayList<Shop_Product>();
		ArrayList<Integer> prodQuanToRemove = new ArrayList<Integer>();
		ArrayList<ArrayList<Shop_Customization>> prodCustToRemove = new ArrayList<ArrayList<Shop_Customization>>();
		for(int s = 0; s < report.getProdCustomizations().size(); s++){
			if(report.getProdQuantity().get(s) == 0){
				prodToRemove.add(report.getCatProds().get(s));
				prodQuanToRemove.add(report.getProdQuantity().get(s));
				prodCustToRemove.add(report.getProdCustomizations().get(s));
			}
		}
		for(int r = 0; r < prodToRemove.size(); r++){
			report.getCatProds().remove(prodToRemove.get(r));
			report.getProdQuantity().remove(prodQuanToRemove.get(r));
			report.getProdCustomizations().remove(prodCustToRemove.get(r));
		}
		int initialSize = report.getCatProds().size();
		int highestQuan;
		int highestQuanIndex = 0;
		for(int index = 0; index < initialSize; index++){
			highestQuan = report.getProdQuantity().get(index);
			
			for(int tempIndex = index; tempIndex < (initialSize - index); tempIndex++){
				if(highestQuan < report.getProdQuantity().get(tempIndex)){
					highestQuan = report.getProdQuantity().get(tempIndex);
					highestQuanIndex = tempIndex;
				}
			}
			
			int tempQ = report.getProdQuantity().get(index);
			report.getProdQuantity().set(index, highestQuan);
			report.getProdQuantity().set(highestQuanIndex, tempQ);
			
			Shop_Product tempProd = report.getCatProds().get(index);
			report.getCatProds().set(index, report.getCatProds().get(highestQuanIndex));
			report.getCatProds().set(highestQuanIndex, tempProd);
			
			ArrayList<Shop_Customization> tempCus = report.getProdCustomizations().get(index);
			report.getProdCustomizations().set(index, report.getProdCustomizations().get(highestQuanIndex));
			report.getProdCustomizations().set(highestQuanIndex, tempCus);
		}

		getParser().getItemPanel().setPreferredSize(new Dimension(350, report.getCatProds().size() * 145));
		for(int i = 0; i < report.getCatProds().size(); i++){
			Color color = new Color(i);
			if(i%2 == 0){
				color = Color.GRAY;
			}
			else
				color = Color.WHITE;

			final int tempIndex = i;
			final JPanel item = new JPanel();
			JLabel prodName = new JLabel(report.getCatProds().get(i).getName() + " " + "(Quantity sold: " + report.getProdQuantity().get(i) + ")");
			JSeparator separator = new JSeparator();
			JLabel prod = new JLabel();
			JScrollPane customiseScrollPane = new JScrollPane();
			
			item.setPreferredSize(new Dimension(360, 135));
			item.setBackground(color);
			item.setOpaque(true);
			FlowLayout layout = (FlowLayout)item.getLayout();
			layout.setAlignment(FlowLayout.LEFT);
			
			prodName.setPreferredSize(new Dimension(260, 20));
			prodName.setHorizontalAlignment(SwingConstants.LEFT);
			item.add(prodName);

			separator.setPreferredSize(new Dimension(340, 5));
			separator.setOrientation(SwingConstants.HORIZONTAL);
			separator.setForeground(Color.GRAY);
			item.add(separator);
			
			prod.setPreferredSize(new Dimension(90, 90));
			prod.setHorizontalAlignment(SwingConstants.LEFT);
			prod.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(report.getCatProds().get(i).getFrontImageUrl()).getScaledInstance(70, 80, Image.SCALE_DEFAULT)));
			item.add(prod);
			
			customiseScrollPane.setPreferredSize(new Dimension(230, 80));
			JPanel customisePanel = new JPanel();
			layout = (FlowLayout)customisePanel.getLayout();
			layout.setAlignment(FlowLayout.LEFT);
			customisePanel.setPreferredSize(new Dimension(report.getProdCustomizations().size() * 50, 50));
				for(int c = 0; c < report.getProdCustomizations().get(i).size(); c++){
					final int tempC = c;
					JLabel customise = new JLabel();
					
					customise.setPreferredSize(new Dimension(50, 50));
					customise.setHorizontalAlignment(SwingConstants.LEFT);
					customise.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(report.getProdCustomizations().get(i).get(c).getFrontCustUrl()).getScaledInstance(50, 50, Image.SCALE_DEFAULT)));
					
					customise.setToolTipText("Click the image to view enlarged image");
					customise.addMouseListener(new MouseListener(){

						@Override
						public void mouseClicked(MouseEvent arg0) {
							JDialog preview = new JDialog(getParser().getParser(), true);
							JTabbedPane previewTabs = new JTabbedPane();
							
							JLabel front = new JLabel();
							front.setPreferredSize(new Dimension(300, 400));
							front.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(report.getProdCustomizations().get(tempIndex).get(tempC).getFrontCustUrl()).getScaledInstance(300, 400, Image.SCALE_DEFAULT)));
							previewTabs.addTab("Front", front);
							
							JLabel back = new JLabel();
							back.setPreferredSize(new Dimension(300, 400));
							back.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(report.getProdCustomizations().get(tempIndex).get(tempC).getBackCustUrl()).getScaledInstance(300, 400, Image.SCALE_DEFAULT)));
							previewTabs.addTab("Back", back);
							
							preview.add(previewTabs);
							
							preview.pack();
							preview.setLocationRelativeTo(getParser().getParser());
							preview.setVisible(true);
						}
						@Override
						public void mouseEntered(MouseEvent arg0) {
						}
						@Override
						public void mouseExited(MouseEvent arg0) {
						}
						@Override
						public void mousePressed(MouseEvent arg0) {
						}
						@Override
						public void mouseReleased(MouseEvent arg0) {
						}
						
					});
					
					customisePanel.add(customise);
				}
				customiseScrollPane.getViewport().add(customisePanel);

			item.add(customiseScrollPane);
			
			getParser().getItemPanel().add(item);
		}
		if(report.getCatProds().size() != 0){
			getParser().getLblProdName().setText(report.getCatProds().get(0).getName());
			getParser().getLblProdQuan().setText("Quantity: " + Integer.toString(report.getProdQuantity().get(0)));
			getParser().getLblProdUnitPrice().setText("Unit Price: $" + Double.toString(report.getCatProds().get(0).getUnitPrice()));
			getParser().getLblProdTotalPrice().setText("Total Price: $" + report.getProdQuantity().get(0)*report.getCatProds().get(0).getUnitPrice());
		}
		else{
			getParser().getLblProdName().setText("");
			getParser().getLblProdQuan().setText("");
			getParser().getLblProdUnitPrice().setText("");
			getParser().getLblProdTotalPrice().setText("");
		}
		getParser().getItemPanel().repaint();
		getParser().getItemPanel().revalidate();
		getParser().getProductPanel().repaint();
		getParser().getProductPanel().revalidate();
	}

	public void generateWorkshopReport(){
		getParser().getWorkshopStatistics().removeAll();
		DefaultPieDataset pieDataset = new DefaultPieDataset();
		
		//How to add data to pie chart dataset
		//pieDataset.setValue("one",new Integer(101));
		
		int totalJoinedQuantity = 0;
		for(int t = 0; t < workshopList.size(); t++){
			totalJoinedQuantity += workshopList.get(t).getJoinedQuantity();
		}
		
		DecimalFormat df = new DecimalFormat("#");
		for(int i = 0; i < workshopList.size(); i++){
			double percent = ((double)workshopList.get(i).getJoinedQuantity()/(double)totalJoinedQuantity)*100;
			pieDataset.setValue(workshopList.get(i).getWorkshopName() + " " + df.format(percent) + "%", workshopList.get(i).getJoinedQuantity());
		}

		JFreeChart chart = ChartFactory.createPieChart("", pieDataset, false, true, false);

		/*PiePlot plot = (PiePlot) chart.getPlot();
		plot.setSectionPaint(workshopList.get(0).getWorkshopName(), Color.RED);
		plot.setSectionPaint(workshopList.get(1).getWorkshopName(), Color.BLUE);
		plot.setSectionPaint(workshopList.get(2).getWorkshopName(), Color.GREEN);
		plot.setSectionPaint(workshopList.get(3).getWorkshopName(), Color.YELLOW);*/
		
		ChartPanel chartPanel = new ChartPanel(chart);
		chartPanel.setPreferredSize(new Dimension(350, 350));
		
		getParser().getWorkshopStatistics().add(chartPanel);
		getParser().getWorkshopStatistics().repaint();
		getParser().getWorkshopStatistics().revalidate();
	}
	
	public void generatePastWorkshops(){
		getParser().getPastWorkshopsPanel().removeAll();
		getParser().getPastWorkshopsPanel().repaint();
		getParser().getPastWorkshopsPanel().revalidate();
		
		workshopList = Workshop_WorkshopEntity.retrieveOBSWorkshopUnderCat(getSelectedCategory(), getParser().getMonthCombo().getSelectedIndex());
		generateWorkshopReport();

		DecimalFormat df = new DecimalFormat("#.##");
		getParser().getPastWorkshopsPanel().setPreferredSize(new Dimension(150, workshopList.size() * 100));
		for(int i = 0; i < workshopList.size(); i++){
			final JPanel workshopPanel = new JPanel();
			
			JLabel workshopName = new JLabel(workshopList.get(i).getWorkshopName());
			JLabel quantity = new JLabel("Capacity: " + workshopList.get(i).getJoinedQuantity() + " / " + workshopList.get(i).getTotalQuantity());
			JLabel percentage = new JLabel("Percentage: " + df.format(((double)workshopList.get(i).getJoinedQuantity()/(double)workshopList.get(i).getTotalQuantity())*100) + "%");
			JSeparator separator = new JSeparator();
			
			workshopPanel.setPreferredSize(new Dimension(150, 90));

			workshopName.setPreferredSize(new Dimension(150, 25));
			workshopName.setFont(new Font("Tahoma", Font.BOLD, 14));
			workshopName.setHorizontalAlignment(SwingConstants.CENTER);
			workshopName.setToolTipText(workshopList.get(i).getWorkshopName());
			workshopPanel.add(workshopName);
			
			quantity.setPreferredSize(new Dimension(150, 20));
			workshopPanel.add(quantity);
			
			percentage.setPreferredSize(new Dimension(150, 20));
			workshopPanel.add(percentage);
			
			separator.setPreferredSize(new Dimension(150, 5));
			separator.setOrientation(SwingConstants.HORIZONTAL);
			separator.setForeground(Color.GRAY);
			workshopPanel.add(separator);
			
			getParser().getPastWorkshopsPanel().add(workshopPanel);
		}
		getParser().getPastWorkshopsPanel().repaint();
		getParser().getPastWorkshopsPanel().revalidate();
	}
}
